package tech.heptagram.staff.starter;

import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import tech.heptagram.core.common.util.JsonUtil;
import tech.heptagram.staff.model.BpmsProcess;
import tech.heptagram.staff.service.BpmsProcessService;
import tech.heptagram.staff.service.DepartmentService;
import tech.heptagram.staff.service.ProcessRecordService;
import tech.heptagram.staff.service.StaffService;
import tech.heptagram.staff.starter.properties.StaffApiProperties;
import tech.heptagram.staff.tools.service.BpmsProcessServiceRestTemplateImpl;
import tech.heptagram.staff.tools.service.DepartmentServiceRestTemplateImpl;
import tech.heptagram.staff.tools.service.ProcessRecordServiceRestTemplateImpl;
import tech.heptagram.staff.tools.service.StaffServiceRestTemplateImpl;

/**
 * @author wang.yuchuan
 * @date 2018/9/6
 */
@Configuration
@ConditionalOnClass({RestTemplate.class})
public class StaffAutoConfiguration {

    @Configuration
    @Profile({"dev", "local", "develop", "test", "default"})
    public static class DevStaffApiUrl {

        @Bean
        @ConditionalOnMissingBean
        public StaffApiProperties staffApiDomain() {
            StaffApiProperties staffApiProperties = new StaffApiProperties();
            staffApiProperties.setStaffApiDomain("https://staffapi.dev.intranet.heptagram.tech");
            return staffApiProperties;
        }
    }

    @Configuration
    @Profile({"pro", "prod"})
    public static class ProdStaffApiUrl {

        @Bean
        @ConditionalOnMissingBean
        public StaffApiProperties staffApiDomain() {
            //https://staffapi.7mxing.com/
            StaffApiProperties staffApiProperties = new StaffApiProperties();
            staffApiProperties.setStaffApiDomain("http://staff-api2.pro-service-intranet");
            return staffApiProperties;
        }
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean({RestTemplate.class, StaffApiProperties.class})
    public StaffService staffService(RestTemplate restTemplate, StaffApiProperties staffApiProperties) {
        StaffServiceRestTemplateImpl staffServiceImpl = new StaffServiceRestTemplateImpl(staffApiProperties.getStaffApiDomain(), restTemplate);
        staffServiceImpl.setDepartmentService(departmentService(restTemplate, staffApiProperties));
        staffServiceImpl.setBpmsProcessService(bpmsProcessService(restTemplate, staffApiProperties));
        staffServiceImpl.setProcessRecordService(processRecordService(restTemplate, staffApiProperties));
        return staffServiceImpl;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean({RestTemplate.class, StaffApiProperties.class})
    public DepartmentService departmentService(RestTemplate restTemplate, StaffApiProperties staffApiProperties) {
        DepartmentServiceRestTemplateImpl departmentServiceRestTemplate = new DepartmentServiceRestTemplateImpl(staffApiProperties.getStaffApiDomain(), restTemplate);
        return departmentServiceRestTemplate;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean({RestTemplate.class, StaffApiProperties.class})
    public BpmsProcessService bpmsProcessService(RestTemplate restTemplate, StaffApiProperties staffApiProperties) {
        BpmsProcessServiceRestTemplateImpl bpmsProcessServiceRestTemplate = new BpmsProcessServiceRestTemplateImpl(staffApiProperties.getStaffApiDomain(), restTemplate);
        return bpmsProcessServiceRestTemplate;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean({RestTemplate.class, StaffApiProperties.class})
    public ProcessRecordService processRecordService(RestTemplate restTemplate, StaffApiProperties staffApiProperties) {
        ProcessRecordServiceRestTemplateImpl processRecordServiceRestTemplate = new ProcessRecordServiceRestTemplateImpl(staffApiProperties.getStaffApiDomain(), restTemplate);
        return processRecordServiceRestTemplate;
    }

    @Configuration
    @ConditionalOnClass({RestTemplate.class})
    public static class RestTemplateConfiguration {
        @Bean
        @ConditionalOnMissingBean
        public RestTemplate restTemplate() {
            RestTemplate restTemplate = new RestTemplate();
            MappingJackson2HttpMessageConverter jsonMapper = new MappingJackson2HttpMessageConverter(JsonUtil.jsonMapperConfig());
            for (HttpMessageConverter<?> httpMessageConverter : restTemplate.getMessageConverters()) {
                if (httpMessageConverter instanceof MappingJackson2HttpMessageConverter) {
                    restTemplate.getMessageConverters().remove(httpMessageConverter);
                    restTemplate.getMessageConverters().add(jsonMapper);
                }
            }
            return restTemplate;
        }
    }
}
